const fs = require("fs");

/**
 * 以node为例子，node中方法都是回调函数，将调用转换成promise方式
 * node中要转换需要引入一个promise库如bluebird，利用其promisify和promisifyall方法
 *原理：将输入的函数A映射称为函数B, B函数的返回值是一个Promise对象，在此Promise对象内部的同步代码中会执行原来的函数A并为其构造一个临时的回调函数，在此临时回调函数内部改变包裹的Promise对象的状态，从而实现数据的传递。

 注意：参数的传递，函数柯里化，apply

 * @param {*} method  要转换的方法
 * @param {*} ctx  上下文
 * @returns promise
 */
function promisfy(method, ctx) {
  ctx = ctx || this;

  return (...args) => {
    return new Promise((resolve, reject) => {
      // method的回调函数
      let callback = () => {
        return function (err, data) {
          // 在回调函数中改变Promise的状态
          if (err) {
            reject(err);
          } else {
            resolve(data);
          }
        };
      };

      // 将回调函数放进参数中
      args.push(callback());

      // 执行method
      method.apply(ctx, args);
    });
  };
}

// 调用
var readFileAsync = promisfy(fs.readFile);
// 相当于函数柯里化，返回一个函数
readFileAsync("./test.js", "utf8").then(function (data) {
  console.log("[ 111 ] >", 111);
  console.log(data);
});
